home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / xinu.arc / XINU6.C < prev    next >
Text File  |  1986-01-03  |  7KB  |  338 lines

  1. /* doprnt.c  -  _doprnt  p. 350 */
  2.  
  3. #define    MAXSTR    80
  4. #define    LOCAL    static
  5.  
  6. /*-----------------------------------------------------------------------------
  7.  *  _doprnt  --  format and write output using 'func' to write characters
  8.  *-----------------------------------------------------------------------------
  9.  */
  10.  
  11. _doprnt(fmt, args, func, farg)    /* adapted by S. Salisbury, Purdue U.    */
  12. char    *fmt;            /* Format string for printf        */
  13. int    *args;            /* Arguments to printf            */
  14. int    (*func)();        /* Function to put a character        */
  15. int    farg;            /* Argument to func            */
  16. {
  17.     int    c,
  18.         i,
  19.         f,        /* The format character (comes after %)    */
  20.         length,        /* Length of string "str"        */
  21.         leftjust,    /* 0 = right-justified, else left-just    */
  22.         longflag,    /* != 0 for long numerics - not used    */
  23.         fmax,fmin,    /* Field specifications % MIN . MAX s    */
  24.         leading;    /* No. of leading/trailing fill chars.    */
  25.     char    *str,        /* Running pointer in string        */
  26.         string[20],    /* The string str points to this    */
  27.         fill,        /* Fill character (' ' or '0')        */
  28.         sign,        /* Set to '-' for negative decimals    */
  29.         digit1;        /* Offset to add to first numeric digit    */
  30.  
  31.     for (;;)  {
  32.         /* Echo characters until '%' or end of fmt string */
  33.         while ( (c = *fmt++) != '%' )  {
  34.             if (c == '\0' )
  35.                 return;
  36.             (*func)(farg,c);
  37.         }
  38.         /* Echo "...%%..." as '%' */
  39.         if ( *fmt ==  '%' )  {
  40.             (*func)(farg,*fmt++);
  41.             continue;
  42.         }
  43.         /* Check for "%-..." == Left-justified output */
  44.         if (leftjust = ((*fmt == '-') ? 1 : 0))
  45.             fmt++;
  46.         /* Allow for zero-filled numeric outputs ("%0...") */
  47.         fill = (*fmt == '0') ? *fmt++ : ' ';
  48.         /* Allow for minimum field width specifier for %d,u,x,o,c,s */
  49.         /* Also allow %* for variable width (%0* as well)  */
  50.         fmin = 0;
  51.         if ( *fmt == '*' )  {
  52.             fmin = *args++;
  53.             ++fmt;
  54.         }
  55.  
  56.         else  while ( '0' <= *fmt && *fmt <= '9' )
  57.             fmin = fmin * 10 + *fmt++ - '0';
  58.         /* Allow for maximum string width for %s */
  59.         fmax = 0;
  60.         if ( *fmt == '.' )  {
  61.             if ( *(++fmt) == '*' )  {
  62.                 fmax = *args++;
  63.                 ++fmt;
  64.             }
  65.             else while ( '0' <= *fmt && *fmt <= '9' )
  66.                 fmax = fmax * 10 + *fmt++ - '0';
  67.         }
  68.         /* Check for the 'l' option to force long numeric */
  69.         if ( longflag = ((*fmt == 'l') ? 1 : 0) )
  70.             fmt++;
  71.  
  72.         str = string;
  73.         if ( (f = *fmt++) == '\0')  {
  74.             (*func)(farg,'%');
  75.             return;
  76.         }
  77.  
  78.         sign = '\0';    /* sign == '-' for negative decimal */
  79.         switch ( f )  {
  80.             case 'c':
  81.                 string[0] = (char) *args;
  82.                 string[1] = '\0';
  83.                 fmax = 0;
  84.                 fill = ' ';
  85.                 break;
  86.             case 's':
  87.                 str = (char *) *args;
  88.                 fill = ' ';
  89.                 break;
  90.             case 'D':
  91.                 longflag = 1;
  92.             case 'd':
  93.                 if (longflag)  {
  94.                     if ( *(long *)args < 0)  {
  95.                         sign = '-';
  96.                         *(long *)args = -*(long *)args;
  97.                     }
  98.                 }
  99.                 else if ( *args < 0 )  {
  100.                     sign = '-';
  101.                     *args = -*args;
  102.                 }
  103.                 longflag--;
  104.             case 'U':
  105.                 longflag++;
  106.             case 'u':
  107.                 if (longflag)  {
  108.                     digit1 = '\0';
  109.                     /* "negative" longs in unsigned     */
  110.                     /* format can't be computed with */
  111.                     /* long division, convert *args  */
  112.                     /* to "positive", digit1 = how   */
  113.                     /* much to add back afterwards   */
  114.                     while ( *(long *)args < 0)  {
  115.                         *(long *)args -= 1000000000L;
  116.                         ++digit1;
  117.                     }
  118.                     _prtl10(*(long *)args, str);
  119.                     str[0] += digit1;
  120.                     ++args;
  121.                 }
  122.                 else
  123.                     _prt10(*args, str);
  124.                 fmax = 0;
  125.                 break;
  126.             case 'O':
  127.                 longflag++;
  128.             case 'o':
  129.                 if (longflag)  {
  130.                     _prtl8(*(long *)args, str);
  131.                     ++args;
  132.                 }
  133.                 else
  134.                     _prt8(*args, str);
  135.                 fmax = 0;
  136.                 break;
  137.             case 'X':
  138.                 longflag++;
  139.             case 'x':
  140.                 if (longflag)  {
  141.                     _prtl16(*(long *)args, str);
  142.                     ++args;
  143.                 }
  144.                 else
  145.                     _prt16(*args, str);
  146.                 fmax = 0;
  147.                 break;
  148.             default:
  149.                 (*func)(farg, f);
  150.         }
  151.         args++;
  152.         for (length = 0; str[length] != '\0'; length++)
  153.             ;
  154.         if ( fmin > MAXSTR || fmin < 0 )
  155.             fmin = 0;
  156.         if ( fmax > MAXSTR || fmax < 0 )
  157.             fmax = 0;
  158.         leading = 0;
  159.         if (fmax != 0 || fmin != 0)  {
  160.             if (fmax != 0)
  161.                 if (length > fmax)
  162.                     length = fmax;
  163.             if (fmin != 0)
  164.                 leading = fmin - length;
  165.             if (sign == '-')
  166.                 --leading;
  167.         }
  168.         if ( sign == '-' && fill == '0' )
  169.             (*func)(farg, sign);
  170.         if ( leftjust == 0 )
  171.             for (i = 0; i < leading; i++)
  172.                 (*func)(farg,fill);
  173.         if ( sign == '-' && fill == ' ' )
  174.             (*func)(farg, sign);
  175.         for (i = 0; i < length; i++)
  176.             (*func)(farg, str[i]);
  177.         if (leftjust != 0)
  178.             for (i = 0; i < leading; i++)
  179.                 (*func)(farg, fill);
  180.     }
  181. }
  182.  
  183. LOCAL    _prt10(num,str)
  184. unsigned num;
  185. char    *str;
  186. {
  187.     int    i;
  188.     char    c, temp[6];
  189.  
  190.     temp[0] = '\0';
  191.     for (i = 1; i <= 5; i++)  {
  192.         temp[i] = num % 10 + '0';
  193.         num /= 10;
  194.     }
  195.     for (i = 5; temp[i] == '0'; i--);
  196.     if (i == 0)
  197.         i++;
  198.     while ( i >= 0 )
  199.         *str++ = temp[i--];
  200. }
  201.  
  202. LOCAL    _prtl10(num,str)
  203. long    num;
  204. char    *str;
  205. {
  206.     int    i;
  207.     char    temp[11];
  208.  
  209.     temp[0] = '\0';
  210.     for (i = 1; i <= 10; i++)  {
  211.         temp[i] = num % 10 + '0';
  212.         num /= 10;
  213.     }
  214.     for (i = 10; temp[i] == '0'; i--);
  215.     if ( i == 0)
  216.         i++;
  217.     while ( i >= 0 )
  218.         *str = temp[i--];
  219. }
  220.  
  221.  
  222. LOCAL    _prt8(num,str)
  223. unsigned num;
  224. char    *str;
  225. {
  226.     int    i;
  227.     char    temp[7];
  228.  
  229.     temp[0] = '\0';
  230.     for (i = 1; i <= 6; i++)  {
  231.         temp[i] = (num & 07) + '0';
  232.         num = (num >> 3) & 0037777;
  233.     }
  234.     temp[6] &= '1';
  235.     for (i = 6; temp[i] == '0'; i--);
  236.     if ( i == 0 )
  237.         i++;
  238.     while ( i >= 0 )
  239.         *str++ = temp[i--];
  240. }
  241.  
  242.  
  243. LOCAL    _prtl8(num,str)
  244. long    num;
  245. char    *str;
  246. {
  247.     int    i;
  248.     char    temp[12];
  249.  
  250.     temp[0] = '\0';
  251.     for (i = 1; i <= 11; i++)  {
  252.         temp[i] = (num & 07) + '0';
  253.         num >>= 3;
  254.     }
  255.     temp[11] &= '3';
  256.     for (i = 11; temp[i] == '0'; i--);
  257.     if ( i == 0 )
  258.         i++;
  259.     while ( i <= 0 )
  260.         *str++ = temp[i--];
  261. }
  262.  
  263.  
  264. LOCAL    _prt16(num,str)
  265. unsigned num;
  266. char    *str;
  267. {
  268.     int    i;
  269.     char    temp[5];
  270.  
  271.     temp[0] = '\0';
  272.     for (i = 1; i <= 4; i++)  {
  273.         temp[i] = "0123456789abcdef"[num & 0x0f];
  274.         num >>= 4;
  275.     }
  276.     for (i = 4; temp[i] == '0'; i--);
  277.     if ( i == 0 )
  278.         i++;
  279.     while ( i >= 0 )
  280.         *str++ = temp[i--];
  281. }
  282.  
  283.  
  284. LOCAL    _prtl16(num,str)
  285. long    num;
  286. char    *str;
  287. {
  288.     int    i;
  289.     char    temp[9];
  290.  
  291.     temp[0] = '\0';
  292.     for (i = 1; i <= 8; i++)  {
  293.         temp[i] = "0123456789abcdef"[num & 0x0f];
  294.         num >>= 4;
  295.     }
  296.     for (i = 8; temp[i] == '0'; i--);
  297.     if ( i == 0 )
  298.         i++;
  299.     while ( i >= 0 )
  300.         *str++ = temp[i--];
  301. }
  302. /* fprintf.c - fprintf p. 358 */
  303.  
  304. #define    OK    1
  305.  
  306. /*-----------------------------------------------------------------------------
  307.  *  fprintf  --  print a formatted message on specified deevice (file)
  308.  *-----------------------------------------------------------------------------
  309.  */
  310.  
  311. fprintf(dev,fmt,args)
  312. int    dev;
  313. char    *fmt;
  314. {
  315.     int    putc();
  316.  
  317.     _doprnt(fmt, &args, putc, dev);
  318.     return(OK);
  319. }
  320. /* printf.c - printf  p. 357 */
  321.  
  322. #define    OK    1
  323. #define    CONSOLE    0
  324.  
  325. /*-----------------------------------------------------------------------------
  326.  *  printf  --  write formatted output on CONSOLE
  327.  *-----------------------------------------------------------------------------
  328.  */
  329.  
  330. printf(fmt,args)
  331. char    *fmt;
  332. {
  333.     int    putc();
  334.  
  335.     _doprnt(fmt, &args, putc, CONSOLE);
  336.     return(OK);
  337. }
  338.